package com.alibaba.citrus.ots.unified.inventory.facade.service;

import com.alibaba.citrus.ots.b2b.trade.order.repository.OrderQueryRepository;
import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.common.lock.RedisLock;
import com.alibaba.citrus.ots.common.log.ModuleEnum;
import com.alibaba.citrus.ots.common.util.SapAndCrmFieldDealUtils;
import com.alibaba.citrus.ots.unified.inventory.functions.allocateOrder.AllocateOrderEntity;
import com.alibaba.citrus.ots.unified.inventory.functions.allocateOrder.AllocateOrderFactory;
import com.alibaba.citrus.ots.unified.inventory.repository.AllocateOrderReadRepository;
import com.alibaba.citrus.ots.unified.inventory.repository.AllocateOrderWriteRepository;
import com.alibaba.citrus.ots.unified.inventory.utils.InfoUtil;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.log.model.OpLogDateTypeEnum;
import com.alibaba.cz.base.tool.log.model.OpLogModel;
import com.alibaba.cz.base.tool.log.model.OperateType;
import com.alibaba.cz.base.tool.log.model.OperatorType;
import com.alibaba.cz.base.tool.message.ErrorCodeException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.middleware.cache.runtime.service.EpochCacheService;
import com.alibaba.lattice2.epoch.middleware.mq.runtime.EpochMessageService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.alibaba.lattice2.epoch.user.dto.LoginUser;
import com.alibaba.lattice2.epoch.user.service.EpochLoginUserService;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.otsb2btradecenter.api.orderwrite.service.OrderWriteService;
import com.epoch.app.otsb2btradecenter.dto.request.ModifyOrderRequest;
import com.epoch.app.otsb2btradecenter.dto.request.OrderQueryRequest;
import com.epoch.app.otsb2btradecenter.sdo.OrderSDO;
import com.epoch.app.otsunifiedinventory.api.allocateapplyorderread.service.AllocateApplyOrderReadService;
import com.epoch.app.otsunifiedinventory.api.allocateorderread.service.AllocateOrderReadService;
import com.epoch.app.otsunifiedinventory.api.allocateorderwrite.service.AllocateOrderWriteService;
import com.epoch.app.otsunifiedinventory.consignmentorder.model.ConsignmentOrder;
import com.epoch.app.otsunifiedinventory.consignmentorder.service.ConsignmentOrderService;
import com.epoch.app.otsunifiedinventory.domain.allocateorder.dto.AllocateOrderLoadListRequest;
import com.epoch.app.otsunifiedinventory.domain.allocateorder.model.AllocateOrder;
import com.epoch.app.otsunifiedinventory.domain.allocateorder.service.AllocateOrderService;
import com.epoch.app.otsunifiedinventory.dto.request.*;
import com.epoch.app.otsunifiedinventory.dto.response.*;
import com.epoch.app.otsunifiedinventory.model.dto.*;
import com.epoch.app.otsunifiedinventory.model.enums.AllocateApplyOrderOperationTypeEnum;
import com.epoch.app.otsunifiedinventory.ouinykfailrecord.dto.BatchCreateRequest;
import com.epoch.app.otsunifiedinventory.ouinykfailrecord.service.OuiNykFailRecordService;
import com.epoch.app.otsunifiedinventory.sdo.AllocateOrderSDO;
import com.epoch.app.otsunifiedinventory.sdo.AllocateOrderWithOrderDetailsSDO;
import com.epoch.app.otsunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author zhangguoqing
 * @date 2021/08/25
 */
@Component
@Primary
public class AllocateOrderWriteServiceImpl  implements AllocateOrderWriteService {

    private Log log = Log.getLogger(AllocateOrderWriteServiceImpl.class);
    private static final String CODE = "code";
    private static final String STATUS = "status";
    private static final String TWENTY_STRING = "20";
    private static final String NINETY_STRING = "90";

    @Resource
    AllocateOrderReadRepository allocateOrderReadRepository;
    @Resource
    EpochMessageService epochMessageService;
    @Resource
    @Qualifier("allocateOrderReadServiceImpl")
    AllocateOrderReadService allocateOrderReadService;
    @Resource
    AllocateOrderWriteRepository allocateOrderWriteRepository;
    @Resource
    private OrderQueryRepository orderQueryServiceRepository;
    @Resource
    private OrderWriteService orderWriteService;
    @Resource
    @Qualifier("allocateApplyOrderReadServiceImpl")
    private AllocateApplyOrderReadService allocateApplyOrderReadService;
    @Resource
    private EpochLoginUserService epochLoginUserService;
    @Autowired
    private OuiNykFailRecordService ouiNykFailRecordService;
    @Resource
    private EpochCacheService epochCacheService;
    @Resource
    ConsignmentOrderService consignmentOrderService;
    @Resource
    AllocateOrderService allocateOrderService;
    //调拨单确认数量先后顺序 缓存
    private static final String ALLOCATE_ORDER_CONFIRM_QUANTITY_KEY = "ALLOCATE_ORDER_CONFIRM_QUANTITY_KEY_";
    // 并发锁key前缀
    private static final String ALLOCATE_ORDER_LOCK_SYNC = "allocateOrderLockSync_";
    //设置sap过期时间为
    private static final Long SAP_TIMESTAMP_CACHE_EXPIRE = 60 * 60 * 24 * 100L;

    /**
     * F-B F-b 销售订单更新/ 退单 /创建 013
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker(value = "013同步调拨单", errorCode = "OTS-03-005-00-15-030")
    public Result<AllocateOrderSalesOrderSyncResponse> salesOrderSync(AllocateOrderSalesOrderSyncRequest request) {
        log.info("AllocateOrderWriteServiceImpl.salesOrderSync,data:" + JSON.toJSONString(request));

        String code = null;
        String allocateApplyOrderCode = "";
        Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTOOld = new Result<>();
        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        AllocateOrderWithOrderDetailsSDO sdoOld = new AllocateOrderWithOrderDetailsSDO();
        try(RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(),ALLOCATE_ORDER_LOCK_SYNC + request.getOutAllocateOrderId(),5 * 60 * 1000,10 * 60 * 1000)){
            if (!lock.lock()){
                throw new FacadeException("OTS-03-005-00-15-096");
            }

            //if (StringUtils.isNotEmpty(request.getCode())) {
            allocateOrderRequest.setAllocateOrderCode(request.getCode());
            allocateOrderRequest.setOutAllocateOrderId(request.getOutAllocateOrderId());
            log.info("AllocateOrderWriteServiceImpl.salesOrderSync.get,code:{}", request.getCode());
            sdoOld = allocateOrderReadRepository.get(allocateOrderRequest);
            log.info("AllocateOrderWriteServiceImpl.salesOrderSync.get,getResultData:{}", JSON.toJSONString(sdoOld));
           // }
            if (Objects.nonNull(sdoOld)&&Objects.nonNull(sdoOld.getAllocateOrderSDO())){
                allocateApplyOrderCode = sdoOld.getAllocateOrderSDO().getAllocateApplyOrderCode();
            }
            //查询老的调拨预报单
            if (StringUtils.isNotEmpty(allocateApplyOrderCode)) {
                QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
                queryAllocateApplyOrderRequest.setCode(allocateApplyOrderCode);
                allocateApplyOrderDetailDTOOld = allocateApplyOrderReadService.queryAllocateApplyOrderByCode(queryAllocateApplyOrderRequest);
            }
            log.info("AllocateOrderWriteServiceImpl.salesOrderSync.salesOrderSync,code:{},request:{}",request.getCode(),JSON.toJSONString(request));
            //判断时间戳 如果时间
            String modifierTime = epochCacheService.get(BcOtsConstants.REDIS_CACHE_CODE(),
                    ALLOCATE_ORDER_CONFIRM_QUANTITY_KEY + request.getOutAllocateOrderId());
            //下发时间戳
            String ext = request.getExt();
            if (StringUtils.isNotBlank(modifierTime)){
                String[] modifierTimeArray = modifierTime.split("\\.");
                String[] extArray = ext.split("\\.");
                if (Long.parseLong(modifierTimeArray[0]) > Long.parseLong(extArray[0])){
                    AllocateOrderSalesOrderSyncResponse response = new AllocateOrderSalesOrderSyncResponse();
                    response.setCode("当前修改时间早于上一次 不允许更新");
                    return Result.success(response);
                }else if (Long.valueOf(modifierTimeArray[0]).longValue() == Long.valueOf(extArray[0]).longValue()){
                    if (Long.parseLong(modifierTimeArray[1]) >= Integer.valueOf(extArray[1]).longValue()){
                        AllocateOrderSalesOrderSyncResponse response = new AllocateOrderSalesOrderSyncResponse();
                        response.setCode("当前修改时间早于上一次 不允许更新");
                        return Result.success(response);
                    }
                }
            }
            //设置缓存
//            epochCacheService.put(BcOtsConstants.REDIS_CACHE_CODE(),
//                    ALLOCATE_ORDER_CONFIRM_QUANTITY_KEY + request.getOutAllocateOrderId(),
//                    ext, SAP_TIMESTAMP_CACHE_EXPIRE, TimeUnit.SECONDS);
            code = allocateOrderWriteRepository.salesOrderSync(request);
            //013请求成功后放入缓存
            if (StringUtils.isNotBlank(code) && code.startsWith("STO")){
                epochCacheService.put(BcOtsConstants.REDIS_CACHE_CODE(),
                        ALLOCATE_ORDER_CONFIRM_QUANTITY_KEY + request.getOutAllocateOrderId(),
                        ext, SAP_TIMESTAMP_CACHE_EXPIRE, TimeUnit.SECONDS);
            }
            log.info("AllocateOrderWriteServiceImpl.salesOrderSync.salesOrderSync,salesOrderSyncResult:{}",code);
        }catch (Exception e){
            log.error("salesOrderSyncError",e);
            throw new FacadeException("OTS-03-005-00-15-098");
        }

        if (StringUtils.isEmpty(request.getCode())) {
            allocateOrderRequest.setAllocateOrderCode(code);
        }
        AllocateOrderWithOrderDetailsSDO sdoNew = allocateOrderReadRepository.get(allocateOrderRequest);
        if (StringUtils.isNotEmpty(request.getCode())){
            saveDocumentLog(sdoOld,sdoNew, Integer.parseInt(AllocateApplyOrderOperationTypeEnum.CHANGE.getValue()), OperatorType.INNER_INTERFACE.getOperatorType());
        }else{
            saveDocumentLog(sdoOld,sdoNew, Integer.parseInt(AllocateApplyOrderOperationTypeEnum.CREATE.getValue()), OperatorType.INNER_INTERFACE.getOperatorType());
        }

        //查询新的调拨预报单
        Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTONew = new Result<>();
        if (StringUtils.isNotBlank(allocateApplyOrderCode)) {
            QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
            queryAllocateApplyOrderRequest.setCode(allocateApplyOrderCode);
            allocateApplyOrderDetailDTONew = allocateApplyOrderReadService.queryAllocateApplyOrderByCode(queryAllocateApplyOrderRequest);
        }
        //添加调拨预报单单据日志
        if (StringUtils.isNotBlank(allocateApplyOrderCode)) {
            Map<String, String> features = new HashMap<>();
            features.put(CODE, allocateApplyOrderCode);
            if (allocateApplyOrderDetailDTONew.getResult() != null &&
                    allocateApplyOrderDetailDTONew.getResult().getStatus() != null){
                features.put(STATUS, allocateApplyOrderDetailDTONew.getResult().getStatus().toString());
            }
//            features.put(STATUS, allocateApplyOrderDetailDTONew.getResult().getStatus().toString());
            AllocateApplyOrderDetailDTO allocateApplyOrderDetailOld = allocateApplyOrderDetailDTOOld.getResult();
            AllocateApplyOrderDetailDTO allocateApplyOrderDetailNew = allocateApplyOrderDetailDTONew.getResult();
            saveAllocateApplyOrderDocumentLog(allocateApplyOrderDetailOld, allocateApplyOrderDetailNew, Integer.valueOf(AllocateApplyOrderOperationTypeEnum.UPDATE.getValue()), features);
        }

        AllocateOrderSalesOrderSyncResponse response = new AllocateOrderSalesOrderSyncResponse();
        response.setCode(code);
        try{
            if (StringUtils.isNotBlank(code)){
//                AllocateOrderDetailsQueryRequest queryRequest = new AllocateOrderDetailsQueryRequest();
//                queryRequest.setCode(code);
//                Result<AllocateOrderDetailsQueryResponse> query = allocateOrderReadService.query(queryRequest);
                AllocateOrderGetMessageRequest allocateOrderGetMessageRequest = new AllocateOrderGetMessageRequest();
                allocateOrderGetMessageRequest.setCode(code);
                Result<AllocateOrderMessageResponse> allocateOrderMessage = allocateOrderReadService.getAllocateOrderMessage(allocateOrderGetMessageRequest);
                Map<String,String> map = Maps.newHashMap();
                map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
                epochMessageService.sendMessage("allocate_order_message","CZ_ALLOCATE","AllocateCreate",code, JSON.toJSONString(allocateOrderMessage.getResult()),
                        map);
            }
        }catch(ErrorCodeException e){
            log.error(e,"AllocateOrderWriteServiceImpl.salesOrderSync exception,code:{},msg:{}",e.getErrorCode(),e.getErrorMessage());
            return Result.fail(e.getErrorCode(), e.getErrorMessage());
        }catch (Throwable e){
            log.error("AllocateOrderWriteServiceImpl.salesOrderSync exception:",e);
            // 异常在FacadeInvokeHandler中会处理
            throw e;
        }
        return Result.success(response);
    }

    /**
     * 009 提交预报单到sap
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker(value = "009提交调拨单到SAP消息",errorCode = "OTS-03-005-00-15-041")
    public Result<AllocateOrderSubmitSAPResponse> submitSAP(AllocateOrderSubmitSAPRequest request) {
        log.info("AllocateOrderWriteServiceImpl.submitSAP.009:{}",JSON.toJSONString(request));
        AllocateOrderRequest r = new AllocateOrderRequest();
        r.setAllocateOrderId(request.getId());
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(r);
        String code = "";
        if (sdo != null && sdo.getAllocateOrderSDO() != null){
            code = sdo.getAllocateOrderSDO().getCode();
        }
        Boolean f = epochMessageService.sendMessage("submit_allocate_order_message","CZ_ALLOCATE","submit_sap",
                code,JSON.toJSONString(sdo));
        log.info("AllocateOrderWriteServiceImpl.submitSAP.009.result:{}",f);

        AllocateOrderSubmitSAPResponse response = new AllocateOrderSubmitSAPResponse();
        return Result.success(response);
    }

    /**
     * 012 F1-B 共享仓到销售单元 货权转移
     * todo 把FacadeInvoker 注解补充完整
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker(value = "012创建总部销售调拨单到SAP消息",errorCode ="OTS-03-005-00-15-040" )
    public Result<AllocateOrderSalesOrderCreateSAPResponse> createSalesOrderSAP(
            AllocateOrderSalesOrderCreateSAPRequest request) {
        log.info("AllocateOrderWriteServiceImpl.createSalesOrderSAP 012提交:" + JSON.toJSONString(request));
        AllocateOrderRequest r = new AllocateOrderRequest();
        r.setAllocateOrderId(request.getId());
        r.setAllocateOrderCode(request.getCode());
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(r);
        String code = "";
        if (sdo != null && sdo.getAllocateOrderSDO() != null){
            code = sdo.getAllocateOrderSDO().getCode();
        }
        Boolean f = epochMessageService.sendMessage("create_sales_order_allocate_order_message","CZ_ALLOCATE","crate_sales_order_sap",
                code,JSON.toJSONString(sdo));
        log.info("AllocateOrderWriteServiceImpl.createSalesOrderSAP.012.result:{}",f);
        AllocateOrderSalesOrderCreateSAPResponse response = new AllocateOrderSalesOrderCreateSAPResponse();
        return Result.success(response);
    }

    /**
     * 总部销售调拨
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker(errorCode = "OTS-03-005-00-15-031",value = "调拨单手动创建")
    public Result<AllocateOrderResponse> manualCreate(AllocateOrderManualCreateRequest request) {
        log.info("AllocateOrderWriteServiceImpl.manualCreate:" + JSON.toJSONString(request));
        //校验渠道编码是不是正确
        if (!(TWENTY_STRING.equals(request.getSapChannel())||NINETY_STRING.equals(request.getSapChannel()))){
            throw new FacadeException("OTS-03-005-00-15-087");
        }
        AllocateOrderResponse response = allocateOrderWriteRepository.manualCreate(request);
        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        allocateOrderRequest.setAllocateOrderCode(response.getCode());
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(allocateOrderRequest);
        saveDocumentLog(new AllocateOrderWithOrderDetailsSDO(),sdo,
                OperateType.CREATE.getOperateType(), OperatorType.USER.getOperatorType());
        log.info("AllocateOrderWriteServiceImpl.manualCreate.result:" + JSON.toJSONString(request));
        return Result.success(response);
    }

    /**
     * 调拨单的创建接口. todo 余红伟 资源层加了事务，这里就不要加了
     * @param allocateOrderCreateRequest
     * @return
     */
    @Override
    @FacadeInvoker(errorCode = "OTS-03-005-00-15-032",value = "平台回复创建调拨单")
    public Result<AllocateOrderCreateResponse> create(AllocateOrderCreateRequest allocateOrderCreateRequest) {
        log.info("AllocateOrderWriteServiceImpl.create 平台回复生成调拨单:" + JSON.toJSONString(allocateOrderCreateRequest));

        String id = allocateOrderWriteRepository.create(allocateOrderCreateRequest);
        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        allocateOrderRequest.setAllocateOrderId(id);
        AllocateOrderWithOrderDetailsSDO freshSdo = allocateOrderReadRepository.get(allocateOrderRequest);
        saveDocumentLog(new AllocateOrderWithOrderDetailsSDO(),freshSdo,
                OperateType.CREATE.getOperateType(), OperatorType.USER.getOperatorType());

//        CompletableFuture.runAsync(()->{
        try{
            if (StringUtils.isNotBlank(id)){
                AllocateOrderRequest request = new AllocateOrderRequest();
                request.setAllocateOrderId(id);
//                    AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(request);
//                    saveDocumentLog(new AllocateOrderWithOrderDetailsSDO(),sdo,
//                            OperateType.CREATE.getOperateType(),OperatorType.INNER_INTERFACE.getOperatorType());
                if (Objects.equals(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType(),allocateOrderCreateRequest.getType())){
                    AllocateOrderSalesOrderCreateSAPRequest createSAPRequest = new AllocateOrderSalesOrderCreateSAPRequest();
                    createSAPRequest.setId(id);
                    //发 创建销售订单到sap 012 货权转移
                    createSalesOrderSAP(createSAPRequest);
                }else {
                    AllocateOrderSubmitSAPRequest submitSAPRequest = new AllocateOrderSubmitSAPRequest();
                    submitSAPRequest.setId(id);
                    submitSAP(submitSAPRequest);
                }
//                AllocateOrderDetailsQueryRequest queryRequest = new AllocateOrderDetailsQueryRequest();
//                queryRequest.setAllocateOrderId(id);
//                Result<AllocateOrderDetailsQueryResponse> queryResponseResult = allocateOrderReadService.query(queryRequest);
                AllocateOrderGetMessageRequest allocateOrderGetMessageRequest = new AllocateOrderGetMessageRequest();
                allocateOrderGetMessageRequest.setId(id);
                Result<AllocateOrderMessageResponse> allocateOrderMessage = allocateOrderReadService.getAllocateOrderMessage(allocateOrderGetMessageRequest);
                String code = null;
                if (allocateOrderMessage != null && allocateOrderMessage.getResult() != null){
                    code = allocateOrderMessage.getResult().getCode();
                }
                Map<String,String> map = Maps.newHashMap();
                map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
                epochMessageService.sendMessage("allocate_order_message","CZ_ALLOCATE","AllocateCreate",
                        code,JSON.toJSONString(allocateOrderMessage.getResult()),
                        map);
            }

        }catch (Throwable e){
            log.error("syncAllocateOrderToSAPError, allocateOrderId:" + id, e);
            throw e;
        }
//        executorService.execute(()-> {
//            try{
//                if (StringUtils.isNotBlank(id)){
//                    AllocateOrderRequest request = new AllocateOrderRequest();
//                    request.setAllocateOrderId(id);
////                    AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(request);
////                    saveDocumentLog(new AllocateOrderWithOrderDetailsSDO(),sdo,
////                            OperateType.CREATE.getOperateType(),OperatorType.INNER_INTERFACE.getOperatorType());
//                    if (Objects.equals(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType(),allocateOrderCreateRequest.getType())){
//                        AllocateOrderSalesOrderCreateSAPRequest createSAPRequest = new AllocateOrderSalesOrderCreateSAPRequest();
//                        createSAPRequest.setId(id);
//                        //发 创建销售订单到sap 012 货权转移
//                        createSalesOrderSAP(createSAPRequest);
//                    }else {
//                        AllocateOrderSubmitSAPRequest submitSAPRequest = new AllocateOrderSubmitSAPRequest();
//                        submitSAPRequest.setId(id);
//                        submitSAP(submitSAPRequest);
//                    }
////                AllocateOrderDetailsQueryRequest queryRequest = new AllocateOrderDetailsQueryRequest();
////                queryRequest.setAllocateOrderId(id);
////                Result<AllocateOrderDetailsQueryResponse> queryResponseResult = allocateOrderReadService.query(queryRequest);
//                    AllocateOrderGetMessageRequest allocateOrderGetMessageRequest = new AllocateOrderGetMessageRequest();
//                    allocateOrderGetMessageRequest.setId(id);
//                    Result<AllocateOrderMessageResponse> allocateOrderMessage = allocateOrderReadService.getAllocateOrderMessage(allocateOrderGetMessageRequest);
//                    String code = null;
//                    if (allocateOrderMessage != null && allocateOrderMessage.getResult() != null){
//                        code = allocateOrderMessage.getResult().getCode();
//                    }
//                    Map<String,String> map = Maps.newHashMap();
//                    map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
//                    epochMessageService.sendMessage("allocate_order_message","CZ_ALLOCATE","AllocateCreate",
//                            code,JSON.toJSONString(allocateOrderMessage.getResult()),
//                            map);
//                }
//
//            }catch (Throwable e){
//                log.error("syncAllocateOrderToSAPError, allocateOrderId:" + id, e);
//                throw e;
//            }
//        });

        AllocateOrderCreateResponse r = new AllocateOrderCreateResponse();
        r.setId(id);
        log.info("AllocateOrderWriteServiceImpl.create 平台回复生成调拨单 restult:" + JSON.toJSONString(r));
        return Result.success(r);
    }

    /**
     * 不用了
     * 调拨单同步 基本数据创建 sap->共享平台 F-F1 创建也包含了更新  008
     * 场景 F-F1
     * @param allocateOrderSyncRequest
     * @return
     */
    @Override
    @FacadeInvoker
    @Deprecated
    public Result<AllocateOrderSyncResponse> sync(AllocateOrderSyncRequest allocateOrderSyncRequest) {
        AllocateOrderSyncResponse r = new AllocateOrderSyncResponse();
        return Result.success(r);
    }

    /**
     * 保存/更新 草稿
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker(value = "调拨单保存",errorCode = "OTS-03-005-00-15-049")
    public Result<AllocateOrderSaveResponse> save(AllocateOrderSaveRequest request) {
        log.info("AllocateOrderWriteServiceImpl.save 调拨单保存:" + request==null?"":JSON.toJSONString(request));

        if (request == null || CollectionUtils.isEmpty(request.getAllocateOrderScItemDetails())){
            throw new FacadeException("OTS-03-005-00-15-058");
//            return Result.fail("allocateOrderSaveError","必须添加货品明细");
        }
        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        allocateOrderRequest.setAllocateOrderCode(request.getCode());
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(allocateOrderRequest);
        String save = allocateOrderWriteRepository.save(request);
        AllocateOrderWithOrderDetailsSDO fresh = allocateOrderReadRepository.get(allocateOrderRequest);
        saveDocumentLog(sdo,fresh,Integer.parseInt(AllocateApplyOrderOperationTypeEnum.UPDATE.getValue()),
                OperatorType.USER.getOperatorType());
        AllocateOrderSaveResponse response = new AllocateOrderSaveResponse();
        response.setCode(save);
        log.info("AllocateOrderWriteServiceImpl.save 调拨单保存:" + JSON.toJSONString(response));
        return Result.success(response);
    }

    /**
     * 提交调拨单 todo FacadeInvoker信息补全 @余红伟
     * @param allocateOrderSubmitRequest
     * @return
     */
    @Override
    @FacadeInvoker(value = "提交调拨单",errorCode = "OTS-03-005-00-15-048")
    public Result<AllocateOrderSubmitResponse> submit(AllocateOrderSubmitRequest allocateOrderSubmitRequest) {
        log.info("AllocateOrderWriteServiceImpl.submit 提交调拨单:" + allocateOrderSubmitRequest==null?"":JSON.toJSONString(allocateOrderSubmitRequest));

        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        allocateOrderRequest.setAllocateOrderCode(allocateOrderSubmitRequest.getCode());
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(allocateOrderRequest);
        String submit = allocateOrderWriteRepository.submit(allocateOrderSubmitRequest);
        AllocateOrderWithOrderDetailsSDO fresh = allocateOrderReadRepository.get(allocateOrderRequest);
        saveDocumentLog(sdo,fresh,Integer.parseInt(AllocateApplyOrderOperationTypeEnum.SUBMIT.getValue()),
                OperatorType.USER.getOperatorType());
        AllocateOrderSubmitResponse response = new AllocateOrderSubmitResponse();
        response.setCode(submit);
        try{
            if (StringUtil.isNotEmpty(submit)){
                Integer type = sdo.getAllocateOrderSDO() == null? null:sdo.getAllocateOrderSDO().getType();
                Long id = sdo.getAllocateOrderSDO() == null? null:sdo.getAllocateOrderSDO().getId();
                //如果是总部销售的 走012接口; 非总部的走009接口重新推送
                if (Objects.equals(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType(),type)){
                    AllocateOrderSalesOrderCreateSAPRequest createSAPRequest = new AllocateOrderSalesOrderCreateSAPRequest();
                    createSAPRequest.setCode(submit);
                    createSalesOrderSAP(createSAPRequest);
                }else {
                    AllocateOrderSubmitSAPRequest submitSAPRequest = new AllocateOrderSubmitSAPRequest();
                    submitSAPRequest.setId(id == null?null:id.toString());
                    submitSAP(submitSAPRequest);
                }
//                AllocateOrderDetailsQueryRequest queryRequest = new AllocateOrderDetailsQueryRequest();
//                queryRequest.setCode(submit);
//                Result<AllocateOrderDetailsQueryResponse> query = allocateOrderReadService.query(queryRequest);
                AllocateOrderGetMessageRequest allocateOrderGetMessageRequest = new AllocateOrderGetMessageRequest();
                allocateOrderGetMessageRequest.setCode(submit);
                Result<AllocateOrderMessageResponse> allocateOrderMessage = allocateOrderReadService.getAllocateOrderMessage(allocateOrderGetMessageRequest);
                Map<String,String> map = Maps.newHashMap();
                map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
                boolean f = epochMessageService.sendMessage("allocate_order_message","CZ_ALLOCATE","AllocateCreate",submit, JSON.toJSONString(allocateOrderMessage.getResult()),
                        map);
            }
        }catch(ErrorCodeException e){
            log.error(e,"AllocateOrderWriteServiceImpl.submit exception,code:{},msg:{}",e.getErrorCode(),e.getErrorMessage());
            return Result.fail(e.getErrorCode(), e.getErrorMessage());
        }catch (Throwable e){
            log.error("submitAllocateOrderError, allocateOrderId:" + submit, e);
            throw e;
        }
        log.info("AllocateOrderWriteServiceImpl.submit 提交调拨单.result:" + JSON.toJSONString(response));
        return Result.success(response);
    }

    @Override
    public Result<AllocateOrderWithdrawResponse> withdraw(AllocateOrderWithdrawRequest allocateOrderWithdrawRequest) {
        return null;
    }

    @Override
    public Result<AllocateOrderUpdateResponse> updateAllocateOrder(AllocateOrderUpdateRequest allocateOrderUpdateRequest) {
        return null;
    }

    @Override
    @FacadeInvoker(value = "调拨单取消",errorCode = "OTS-03-005-00-15-047")
    public Result<AllocateOrderCancelResponse> cancel(AllocateOrderCancelRequest allocateOrderCancelRequest) {
        log.info("AllocateOrderWriteServiceImpl.cancel 调拨单取消:" + allocateOrderCancelRequest==null?"":JSON.toJSONString(allocateOrderCancelRequest));

        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        allocateOrderRequest.setAllocateOrderCode(allocateOrderCancelRequest.getCode());
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(allocateOrderRequest);
        AllocateOrderCancelResponse response = allocateOrderWriteRepository.cancel(allocateOrderCancelRequest);
        saveDocumentLog(sdo,new AllocateOrderWithOrderDetailsSDO(),
                Integer.parseInt(AllocateApplyOrderOperationTypeEnum.CANCEL.getValue()),
                OperatorType.USER.getOperatorType());
        log.info("AllocateOrderWriteServiceImpl.cancel 调拨单取消 result:" + JSON.toJSONString(response));
        return Result.success(response);
    }

    /**
     * 发货
     * @param allocateOrderShippedRequest
     * @return
     */
    @Override
    @FacadeInvoker(value = "调拨单发货", errorCode = "OTS-03-005-00-15-042")
    public Result<AllocateOrderShippedResponse> shipped(AllocateOrderShippedRequest allocateOrderShippedRequest) {
        log.info("materialHandle_shipped_request,material:{}, request:{}", allocateOrderShippedRequest.getOutMaterialCertificateId(), JSON.toJSONString(allocateOrderShippedRequest));
        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        allocateOrderRequest.setAllocateOrderId(allocateOrderShippedRequest.getId());
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(allocateOrderRequest);
        log.info("AllocateOrderWriteServiceImpl.shipped.before:{}",JSON.toJSONString(sdo));
        if (StringUtils.isEmpty(getOutAllocateOrderId(sdo))) {
            log.error("AllocateOrderWriteServiceImpl.shipped.outAllocateOrderId.isEmpty");
            throw new FacadeException("OTS-03-005-00-15-042");
        }
        AllocateOrderShippedResponse response = new AllocateOrderShippedResponse();
        try(RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(),ALLOCATE_ORDER_LOCK_SYNC + getOutAllocateOrderId(sdo),5 * 60 * 1000,10 * 60 * 1000)){
            if (!lock.lock()){
                throw new FacadeException("OTS-03-005-00-15-096");
            }
            response = allocateOrderWriteRepository.shipped(allocateOrderShippedRequest);
        }catch (Exception e){
            log.error("allocateOrderShippedError",e);
            throw new FacadeException("OTS-03-005-00-15-042");
        }
        AllocateOrderWithOrderDetailsSDO fresh = allocateOrderReadRepository.get(allocateOrderRequest);
        log.info("AllocateOrderWriteServiceImpl.shipped.after:{}",JSON.toJSONString(fresh));
        saveDocumentLog(sdo,fresh, Integer.parseInt(AllocateApplyOrderOperationTypeEnum.Shipped.getValue()),
                OperatorType.INNER_INTERFACE.getOperatorType());
        log.info("materialHandle_shipped_response,material:{}, response:{}", allocateOrderShippedRequest.getOutMaterialCertificateId(), JSON.toJSONString(response));
        return Result.success(response);
    }

    @Override
    @FacadeInvoker(value = "调拨单收货", errorCode = "OTS-03-005-00-15-043")
    public Result<AllocateOrderReceivedResponse> received(AllocateOrderReceivedRequest allocateOrderReceivedRequest) {
        log.info("materialHandle_received_request,material:{}, request:{}", allocateOrderReceivedRequest.getOutMaterialCertificateId(), JSON.toJSONString(allocateOrderReceivedRequest));
        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        allocateOrderRequest.setAllocateOrderId(allocateOrderReceivedRequest.getId());
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(allocateOrderRequest);
        log.info("AllocateOrderWriteServiceImpl.received.before:{}",JSON.toJSONString(sdo));
        if (StringUtils.isEmpty(getOutAllocateOrderId(sdo))) {
            log.error("AllocateOrderWriteServiceImpl.received.outAllocateOrderId.isEmpty");
            throw new FacadeException("OTS-03-005-00-15-043");
        }
        AllocateOrderReceivedResponse response = new AllocateOrderReceivedResponse();
        try(RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(),ALLOCATE_ORDER_LOCK_SYNC + getOutAllocateOrderId(sdo),5 * 60 * 1000,10 * 60 * 1000)){
            if (!lock.lock()){
                throw new FacadeException("OTS-03-005-00-15-096");
            }
            response = allocateOrderWriteRepository.received(allocateOrderReceivedRequest);
        }catch (Exception e){
            log.error("allocateOrderReceivedError",e);
            throw new FacadeException("OTS-03-005-00-15-043");
        }
//        AllocateOrderReceivedResponse response = allocateOrderWriteRepository.received(allocateOrderReceivedRequest);
        AllocateOrderWithOrderDetailsSDO fresh = allocateOrderReadRepository.get(allocateOrderRequest);
        log.info("AllocateOrderWriteServiceImpl.received.after:{}",JSON.toJSONString(fresh));
        saveDocumentLog(sdo,fresh,Integer.parseInt(AllocateApplyOrderOperationTypeEnum.RECEIVED.getValue()),
                OperatorType.INNER_INTERFACE.getOperatorType());
        log.info("materialHandle_received_response,material:{}, response:{}", allocateOrderReceivedRequest.getOutMaterialCertificateId(), JSON.toJSONString(response));
        return Result.success(response);
    }

    @Override
    public Result<AllocateOrderResponse> backward(AllocateOrderBackwardDTO allocateOrderBackwardDTO) {
        return null;
    }

    /**
     * 销售订单更新
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker
    @Deprecated
    public Result<AllocateOrderSalesOrderUpdateResponse> salesOrderUpdate(AllocateOrderSalesOrderUpdateRequest request) {
        log.info("AllocateOrderWriteServiceImpl.salesOrderUpdate :" + request==null?"":JSON.toJSONString(request));

        AllocateOrderEntity entity = AllocateOrderFactory.salesOrderUpdate(request);
        String id = entity.salesOrderUpdate();
        AllocateOrderSalesOrderUpdateResponse response = new AllocateOrderSalesOrderUpdateResponse();
        response.setCode(id);
        return null;
    }

    /**
     * 008 同步更新调拨单
     * @param allocateOrderSyncRequest
     * @return
     */
    @Override
    @FacadeInvoker(value = "008同步调拨单",errorCode = "OTS-03-005-00-15-044")
    public Result<AllocateOrderSyncResponse> passiveSync(AllocateOrderSyncRequest allocateOrderSyncRequest) {
        log.info("sap008接口入参："+ JSONObject.toJSONString(allocateOrderSyncRequest));

        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        AllocateOrderWithOrderDetailsSDO sdoOld = new AllocateOrderWithOrderDetailsSDO();
        AllocateOrderSyncResponse allocateOrderSyncResponse = null;
        Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTOOld = new Result<>();
        try(RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(),ALLOCATE_ORDER_LOCK_SYNC + allocateOrderSyncRequest.getOutAllocateOrderId(),5 * 60 * 1000,10 * 60 * 1000)){
            if (!lock.lock()){
                throw new FacadeException("OTS-03-005-00-15-096");
            }

            if (Objects.nonNull(allocateOrderSyncRequest.getAllocateApplyOrderCode())) {
                QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
                queryAllocateApplyOrderRequest.setCode(allocateOrderSyncRequest.getAllocateApplyOrderCode());
                allocateApplyOrderDetailDTOOld = allocateApplyOrderReadService.queryAllocateApplyOrderByCode(queryAllocateApplyOrderRequest);
            }
            if (StringUtils.isNotEmpty(allocateOrderSyncRequest.getCode())||StringUtils.isNotEmpty(allocateOrderSyncRequest.getOutAllocateOrderId())) {
                allocateOrderRequest.setAllocateOrderCode(allocateOrderSyncRequest.getCode());
                allocateOrderRequest.setOutAllocateOrderId(allocateOrderSyncRequest.getOutAllocateOrderId());
                sdoOld = allocateOrderReadRepository.get(allocateOrderRequest);
            }
            //判断时间戳 如果时间
            String modifierTime = epochCacheService.get(BcOtsConstants.REDIS_CACHE_CODE(),
                    ALLOCATE_ORDER_CONFIRM_QUANTITY_KEY + allocateOrderSyncRequest.getOutAllocateOrderId());
            //下发时间戳
            String ext = allocateOrderSyncRequest.getExt();
            if (StringUtils.isNotBlank(modifierTime)){
                String[] modifierTimeArray = modifierTime.split("\\.");
                String[] extArray = ext.split("\\.");
                if (Long.parseLong(modifierTimeArray[0]) > Long.parseLong(extArray[0])){
                    AllocateOrderSyncResponse response = new AllocateOrderSyncResponse();
                    response.setCode("当前修改时间早于上一次 不允许更新");
                    return Result.success(response);
                }else if (Long.valueOf(modifierTimeArray[0]).longValue() == Long.valueOf(extArray[0]).longValue()) {
                    if (Long.parseLong(modifierTimeArray[1]) >= Long.parseLong(extArray[1])){
                        AllocateOrderSyncResponse response = new AllocateOrderSyncResponse();
                        response.setCode("当前修改时间早于上一次 不允许更新");
                        return Result.success(response);
                    }
                }
            }
            //设置缓存
//            epochCacheService.put(BcOtsConstants.REDIS_CACHE_CODE(),
//                    ALLOCATE_ORDER_CONFIRM_QUANTITY_KEY + allocateOrderSyncRequest.getOutAllocateOrderId(),
//                    ext, SAP_TIMESTAMP_CACHE_EXPIRE, TimeUnit.SECONDS);
            allocateOrderSyncResponse = allocateOrderWriteRepository.passiveSync(allocateOrderSyncRequest);
            //008执行成功了 记录缓存时间戳
            if (Objects.nonNull(allocateOrderSyncResponse) && StringUtils.isNotBlank(allocateOrderSyncResponse.getCode())
                && allocateOrderSyncResponse.getCode().startsWith("STO")){
                epochCacheService.put(BcOtsConstants.REDIS_CACHE_CODE(),
                        ALLOCATE_ORDER_CONFIRM_QUANTITY_KEY + allocateOrderSyncRequest.getOutAllocateOrderId(),
                        ext, SAP_TIMESTAMP_CACHE_EXPIRE, TimeUnit.SECONDS);
            }
        }catch (Exception e){
            log.error("passiveSyncAllocateOrderError",e);
            throw new FacadeException("OTS-03-005-00-15-097");
        }

        if (StringUtils.isEmpty(allocateOrderSyncRequest.getCode())) {
            allocateOrderRequest.setAllocateOrderCode(allocateOrderSyncResponse.getCode());
        }
        AllocateOrderWithOrderDetailsSDO sdoNew = allocateOrderReadRepository.get(allocateOrderRequest);
        if (StringUtils.isNotEmpty(allocateOrderSyncRequest.getCode())) {
            log.info("008接口记录日志更新方法：旧值：{}，新值:{}",JSONObject.toJSONString(sdoOld),JSONObject.toJSONString(sdoNew));
            if (allocateOrderSyncResponse != null && StringUtils.isNotBlank(allocateOrderSyncResponse.getCode())
                    && allocateOrderSyncResponse.getCode().startsWith("STO")){
                saveDocumentLog(sdoOld,sdoNew==null?sdoOld:sdoNew, Integer.parseInt(AllocateApplyOrderOperationTypeEnum.CHANGE.getValue()), OperatorType.USER.getOperatorType());
            }
        }else{
            log.info("008接口记录日志创建方法：旧值：{}，新值:{}",JSONObject.toJSONString(sdoOld),JSONObject.toJSONString(sdoNew));
            if (allocateOrderSyncResponse != null && StringUtils.isNotBlank(allocateOrderSyncResponse.getCode())
                    && allocateOrderSyncResponse.getCode().startsWith("STO")){
                saveDocumentLog(sdoOld,sdoNew==null?sdoOld:sdoNew, Integer.parseInt(AllocateApplyOrderOperationTypeEnum.CREATE.getValue()), OperatorType.USER.getOperatorType());
            }
        }

        Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTONew = new Result<>();
        if (StringUtils.isNotBlank(allocateOrderSyncRequest.getAllocateApplyOrderCode())) {
            QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
            queryAllocateApplyOrderRequest.setCode(allocateOrderSyncRequest.getAllocateApplyOrderCode());
            allocateApplyOrderDetailDTONew = allocateApplyOrderReadService.queryAllocateApplyOrderByCode(queryAllocateApplyOrderRequest);
        }
        //添加调拨预报单单据日志
        if (StringUtils.isNotBlank(allocateOrderSyncRequest.getAllocateApplyOrderCode())) {
            Map<String, String> features = new HashMap<>();
            features.put(CODE, allocateOrderSyncRequest.getAllocateApplyOrderCode());
            if (allocateApplyOrderDetailDTONew.getResult() != null &&
                    allocateApplyOrderDetailDTONew.getResult().getStatus() != null){
                features.put(STATUS, allocateApplyOrderDetailDTONew.getResult().getStatus().toString());
            }
//            features.put(STATUS, allocateApplyOrderDetailDTONew.getResult().getStatus().toString());
            AllocateApplyOrderDetailDTO allocateApplyOrderDetailOld = allocateApplyOrderDetailDTOOld.getResult();
            AllocateApplyOrderDetailDTO allocateApplyOrderDetailNew = allocateApplyOrderDetailDTONew.getResult();
            saveAllocateApplyOrderDocumentLog(allocateApplyOrderDetailOld, allocateApplyOrderDetailNew, Integer.valueOf(AllocateApplyOrderOperationTypeEnum.UPDATE.getValue()), features);
        }
        try{
            if (allocateOrderSyncResponse != null && StringUtils.isNotBlank(allocateOrderSyncResponse.getCode())
                    && allocateOrderSyncResponse.getCode().startsWith("STO")){
//                AllocateOrderDetailsQueryRequest queryRequest = new AllocateOrderDetailsQueryRequest();
//                queryRequest.setCode(allocateOrderSyncResponse.getCode());
//                Result<AllocateOrderDetailsQueryResponse> query = allocateOrderReadService.query(queryRequest);
                AllocateOrderGetMessageRequest allocateOrderGetMessageRequest = new AllocateOrderGetMessageRequest();
                allocateOrderGetMessageRequest.setCode(allocateOrderSyncResponse.getCode());
                Result<AllocateOrderMessageResponse> allocateOrderMessage = allocateOrderReadService.getAllocateOrderMessage(allocateOrderGetMessageRequest);
                Map<String,String> map = Maps.newHashMap();
                map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
                epochMessageService.sendMessage("allocate_order_message","CZ_ALLOCATE","AllocateCreate",
                        allocateOrderSyncResponse.getCode(),JSON.toJSONString(allocateOrderMessage.getResult()),map);
            }
        }catch(ErrorCodeException e){
            log.error(e,"AllocateOrderWriteServiceImpl.passiveSync exception,code:{},msg:{}",e.getErrorCode(),e.getErrorMessage());
            return Result.fail(e.getErrorCode(), e.getErrorMessage());
        }catch (Throwable e){
            log.error("AllocateOrderWriteServiceImpl.passiveSync exception:",e);
            // 异常在FacadeInvokeHandler中会处理
            throw e;
        }
        return Result.success(allocateOrderSyncResponse);
    }


    /**
     * 创建退单 -- 传入发票后生成对应的调拨单
     * @param allocateOrderReturnOrderRequest
     * @return
     */
    @Override
    @FacadeInvoker(value = "创建退单",errorCode = "OTS-03-005-00-15-045")
    public Result<AllocateOrderReturnOrderResponse> returnOrder(AllocateOrderReturnOrderRequest allocateOrderReturnOrderRequest) {
        log.info("AllocateOrderWriteServiceImpl.returnOrder :" + allocateOrderReturnOrderRequest==null?"":JSON.toJSONString(allocateOrderReturnOrderRequest));


        AllocateOrderReturnOrderResponse response = allocateOrderWriteRepository.returnOrder(allocateOrderReturnOrderRequest);
        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        allocateOrderRequest.setAllocateOrderCode(response.getCode());
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(allocateOrderRequest);
        saveDocumentLog(new AllocateOrderWithOrderDetailsSDO(),sdo,
                Integer.parseInt(AllocateApplyOrderOperationTypeEnum.CREATE.getValue()),
                OperatorType.USER.getOperatorType());
        if (response != null && StringUtils.isNotBlank(response.getCode())){
            String submit = response.getCode();
            try{
                if (StringUtil.isNotEmpty(submit)){
                    AllocateOrderSalesOrderCreateSAPRequest createSAPRequest = new AllocateOrderSalesOrderCreateSAPRequest();
                    createSAPRequest.setCode(submit);
                    createSalesOrderSAP(createSAPRequest);
//                    AllocateOrderDetailsQueryRequest queryRequest = new AllocateOrderDetailsQueryRequest();
//                    queryRequest.setCode(submit);
//                    Result<AllocateOrderDetailsQueryResponse> query = allocateOrderReadService.query(queryRequest);
                    AllocateOrderGetMessageRequest allocateOrderGetMessageRequest = new AllocateOrderGetMessageRequest();
                    allocateOrderGetMessageRequest.setCode(submit);
                    Result<AllocateOrderMessageResponse> allocateOrderMessage = allocateOrderReadService.getAllocateOrderMessage(allocateOrderGetMessageRequest);
                    Map<String,String> map = Maps.newHashMap();
                    map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
                    epochMessageService.sendMessage("allocate_order_message","CZ_ALLOCATE","AllocateCreate",
                            submit,JSON.toJSONString(allocateOrderMessage.getResult()),map);
                }
            }catch(ErrorCodeException e){
                log.error(e,"AllocateOrderWriteServiceImpl.passiveSync exception,code:{},msg:{}",e.getErrorCode(),e.getErrorMessage());
                return Result.fail(e.getErrorCode(), e.getErrorMessage());
            }catch (Throwable e) {
                log.error("submitAllocateOrderError, allocateOrderId:" + submit, e);
                // 异常在FacadeInvokeHandler中会处理
                throw e;
            }
        }
        log.info("AllocateOrderWriteServiceImpl.returnOrder.result :" + response==null?"":JSON.toJSONString(response));

        return Result.success(response);
    }


    @FacadeInvoker(value = "调拨单交货",errorCode = "OTS-03-005-00-15-046")
    @Override
    public Result<AllocateOrderDeliveryResponse> delivered(AllocateOrderDeliveryRequest allocateOrderDeliveryRequest) {
        log.info("AllocateOrderWriteServiceImpl.delivered.request:" + JSON.toJSONString(allocateOrderDeliveryRequest));
        AllocateOrderDeliveryResponse response = new AllocateOrderDeliveryResponse();
        if (StringUtils.isAllBlank(allocateOrderDeliveryRequest.getOutAllocateOrderId(), allocateOrderDeliveryRequest.getCode())) {
            log.info("deliveredFreshSaleOrderReturn, code:{}, outAllocateOrderId:{}", allocateOrderDeliveryRequest.getCode(), allocateOrderDeliveryRequest.getOutAllocateOrderId());
            return Result.success(response);
        }
        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
       // allocateOrderRequest.setAllocateOrderCode(allocateOrderDeliveryRequest.getCode());
        allocateOrderRequest.setOutAllocateOrderId(allocateOrderDeliveryRequest.getOutAllocateOrderId());
        AllocateOrderWithOrderDetailsSDO sdo = allocateOrderReadRepository.get(allocateOrderRequest);
        if (sdo == null || sdo.getAllocateOrderSDO() == null || sdo.getAllocateOrderSDO().getId() == null){
            log.error("AllocateOrderWriteServiceImpl.delivered.error:{}",JSON.toJSONString(allocateOrderDeliveryRequest));
        }
        if (StringUtils.isEmpty(getOutAllocateOrderId(sdo))) {
            log.error("AllocateOrderWriteServiceImpl.delivered.outAllocateOrderId.isEmpty");
            throw new FacadeException("OTS-03-005-00-15-046");
        }
        //交货日志写在下一层
        try(RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(),ALLOCATE_ORDER_LOCK_SYNC + getOutAllocateOrderId(sdo),5 * 60 * 1000,10 * 60 * 1000)){
            if (!lock.lock()){
                throw new FacadeException("OTS-03-005-00-15-096");
            }
            response = allocateOrderWriteRepository.delivered(allocateOrderDeliveryRequest);
        }catch (Exception e){
            log.error("allocateOrderDeliveredError",e);
            throw new FacadeException("OTS-03-005-00-15-046");
        }
//        AllocateOrderDeliveryResponse response = allocateOrderWriteRepository.delivered(allocateOrderDeliveryRequest);
        log.info("AllocateOrderWriteServiceImpl.delivered.result:" + JSON.toJSONString(response));
        return Result.success(response);
    }

    @Override
    @FacadeInvoker(value = "交货单删除撤销交货", errorCode = "OTS-03-005-00-15-051")
    public Result<AllocateOrderCancelDeliveredResponse> cancelDelivered(AllocateOrderCancelDeliveredRequest allocateOrderCancelDeliveredRequest) {
        //日志写在下一层
        log.info("调拨单交货单:" + JSON.toJSONString(allocateOrderCancelDeliveredRequest));
        AllocateOrderCancelDeliveredResponse response = new AllocateOrderCancelDeliveredResponse();
        //获取删除的交货单
        ConsignmentOrderLoadListRequest request = new ConsignmentOrderLoadListRequest();
        request.setOuterDeliveryOrderId(SapAndCrmFieldDealUtils.generateIdField(allocateOrderCancelDeliveredRequest.getDeliveryOrderId()));
        Result<List<ConsignmentOrder>> loadConsignmentOrderList = consignmentOrderService.loadConsignmentOrderList(request);
        if (loadConsignmentOrderList == null || CollectionUtils.isEmpty(loadConsignmentOrderList.getResult())) {
            return Result.success(response);
        }
        List<String> outCodes = loadConsignmentOrderList.getResult().stream().map(ConsignmentOrder::getOuterStoOrderId)
                .filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(outCodes)) {
            return Result.success(response);
        }
        String code = outCodes.get(0);
        AllocateOrderLoadListRequest allocateOrderLoadListRequest = new AllocateOrderLoadListRequest();
        code = InfoUtil.addZeroPrefix(code);
        allocateOrderLoadListRequest.setOutAllocateOrderId(code);
        Result<List<AllocateOrder>> listResult = allocateOrderService.loadAllocateOrderList(allocateOrderLoadListRequest);
        if (listResult == null || CollectionUtils.isEmpty(listResult.getResult())){
            return Result.success(response);
        }
        AllocateOrder allocateOrder = listResult.getResult().get(0);
        if (StringUtils.isEmpty(allocateOrder.getOutAllocateOrderId())) {
            log.error("AllocateOrderWriteServiceImpl.cancelDelivered.outAllocateOrderId.isEmpty");
            throw new FacadeException("OTS-03-005-00-15-051");
        }
        try(RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(),ALLOCATE_ORDER_LOCK_SYNC + allocateOrder.getOutAllocateOrderId(),5 * 60 * 1000,10 * 60 * 1000)){
            if (!lock.lock()){
                throw new FacadeException("OTS-03-005-00-15-096");
            }
            response = allocateOrderWriteRepository.cancelDelivered(allocateOrderCancelDeliveredRequest);
        }catch (Throwable e){
            log.error("allocateOrderCancelDeliveredError",e);
            throw new FacadeException("OTS-03-005-00-15-099");
        }

//        response = allocateOrderWriteRepository.cancelDelivered(allocateOrderCancelDeliveredRequest);
        return Result.success(response);
    }

    /**
     * sap报文里的订单id转换成内部主键id  sap: 1开头 中间补0  总长度10
     * @param sapOrderId
     * @return
     */
    private String convertTradeOrderId(String sapOrderId){
        if (StringUtils.isNotBlank(sapOrderId)){
            return sapOrderId.trim().length() == 10 ?sapOrderId.trim().replaceFirst("^10+","")
                    : sapOrderId.trim();
        }
        return null;
    }

    @FacadeInvoker(value = "调拨单回调",errorCode = "OTS-03-005-00-15-039")
    @Override
    public Result<AllocateOrderNotifyResponse> notify(AllocateOrderNotifyRequest allocateOrderNotifyRequest) {
        log.info("AllocateOrderWriteServiceImpl.notify.request:" + JSON.toJSONString(allocateOrderNotifyRequest));
        //012接口回调需要区分是调拨还是销售（F-B销售订单及老的调拨单都是调sap 012接口）
        OrderQueryRequest queryRequest = new OrderQueryRequest();
        queryRequest.setId(convertTradeOrderId(allocateOrderNotifyRequest.getInnerKey()));
        OrderSDO orderSDO = orderQueryServiceRepository.querySingle(queryRequest);
        if (null != orderSDO) {
            ModifyOrderRequest modifyOrderRequest = new ModifyOrderRequest();
            modifyOrderRequest.setSuccess(allocateOrderNotifyRequest.getSuccess());
            modifyOrderRequest.setOuterKey(allocateOrderNotifyRequest.getOuterKey());
            modifyOrderRequest.setInnerKey(allocateOrderNotifyRequest.getInnerKey());
            modifyOrderRequest.setMessage(allocateOrderNotifyRequest.getMessage());
            orderWriteService.modifySaleOrder(modifyOrderRequest);
            AllocateOrderNotifyResponse response = new AllocateOrderNotifyResponse();
            response.setSuccess(allocateOrderNotifyRequest.getSuccess());
            response.setInnerKey(allocateOrderNotifyRequest.getInnerKey());
            response.setOuterKey(allocateOrderNotifyRequest.getOuterKey());
            response.setMessage(allocateOrderNotifyRequest.getMessage());
            return Result.success(response);
        }
        AllocateOrderNotifyResponse response = allocateOrderWriteRepository.notify(allocateOrderNotifyRequest);
        log.info("AllocateOrderWriteServiceImpl.notify.result:" + JSON.toJSONString(response));
        return Result.success(response);
    }

    /**
     * 撤回发货
     * @param allocateOrderCancelShippedRequest
     * @return
     */
    @Override
    @FacadeInvoker(value = "调拨单撤销发货",errorCode = "OTS-03-005-00-15-038")
    public Result<AllocateOrderCancelShippedResponse> cancelShipped(AllocateOrderCancelShippedRequest allocateOrderCancelShippedRequest) {
        log.info("materialHandle_cancelShipped_request,material:{}, request:{}", allocateOrderCancelShippedRequest.getOutMaterialCertificateId(), JSON.toJSONString(allocateOrderCancelShippedRequest));
        AllocateOrderRequest allocateOrderRequest = new AllocateOrderRequest();
        allocateOrderRequest.setAllocateOrderId(allocateOrderCancelShippedRequest.getId());
        AllocateOrderInfo info = allocateOrderReadRepository.find(allocateOrderRequest);
        if (Objects.isNull(info) || StringUtils.isEmpty(info.getOutAllocateOrderId())) {
            log.error("AllocateOrderWriteServiceImpl.cancelShipped.outAllocateOrderId.isEmpty");
            throw new FacadeException("OTS-03-005-00-15-038");
        }
        AllocateOrderCancelShippedResponse response = new AllocateOrderCancelShippedResponse();
        try(RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(),ALLOCATE_ORDER_LOCK_SYNC + info.getOutAllocateOrderId(),5 * 60 * 1000,10 * 60 * 1000)){
            if (!lock.lock()){
                throw new FacadeException("OTS-03-005-00-15-096");
            }
            response = allocateOrderWriteRepository.cancelShipped(allocateOrderCancelShippedRequest);
        }catch (Exception e){
            log.error("allocateOrderCancelShippedError",e);
            throw new FacadeException("OTS-03-005-00-15-038");
        }
//        AllocateOrderCancelShippedResponse response = allocateOrderWriteRepository.cancelShipped(allocateOrderCancelShippedRequest);
//        AllocateOrderShippedResponse response = allocateOrderWriteRepository.shipped(allocateOrderShippedRequest);
        AllocateOrderInfo fresh = allocateOrderReadRepository.find(allocateOrderRequest);
        Map<String,String> features = Maps.newHashMap();
        saveDocumentLog(info,fresh, AllocateApplyOrderOperationTypeEnum.CANCELSHIPPED.getValue(),
                OperatorType.INNER_INTERFACE.getOperatorType(),features);
        log.info("materialHandle_cancelShipped_response,material:{}, request:{}", allocateOrderCancelShippedRequest.getOutMaterialCertificateId(), JSON.toJSONString(response));
        return Result.success(response);
    }
    @Override
    @FacadeInvoker(value = "调拨单取消收货" ,errorCode = "OTS-03-005-00-15-055")
    /**
     * 撤销收货
     */
    public Result<AllocateOrderCancelReceivedResponse> cancelReceived(AllocateOrderCancelReceivedRequest allocateOrderCancelReceivedRequest) {
        log.info("materialHandle_cancelReceived_request,material:{}, request:{}", allocateOrderCancelReceivedRequest.getOutMaterialCertificateId(), JSON.toJSONString(allocateOrderCancelReceivedRequest));
        AllocateOrderRequest request = new AllocateOrderRequest();
        request.setAllocateOrderId(allocateOrderCancelReceivedRequest.getId());
        AllocateOrderInfo old = allocateOrderReadRepository.find(request);
        if (Objects.isNull(old) || StringUtils.isEmpty(old.getOutAllocateOrderId())) {
            log.error("AllocateOrderWriteServiceImpl.cancelReceived.outAllocateOrderId.isEmpty");
            throw new FacadeException("OTS-03-005-00-15-055");
        }
        AllocateOrderCancelReceivedResponse response = new AllocateOrderCancelReceivedResponse();
        try(RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(),ALLOCATE_ORDER_LOCK_SYNC + old.getOutAllocateOrderId(),5 * 60 * 1000,10 * 60 * 1000)){
            if (!lock.lock()){
                throw new FacadeException("OTS-03-005-00-15-096");
            }
            response = allocateOrderWriteRepository.cancelReceived(allocateOrderCancelReceivedRequest);
        }catch (Exception e){
            log.error("allocateOrderCancelReceivedError",e);
            throw new FacadeException("OTS-03-005-00-15-055");
        }
//        AllocateOrderCancelReceivedResponse response = allocateOrderWriteRepository.cancelReceived(allocateOrderCancelReceivedRequest);
        AllocateOrderInfo fresh = allocateOrderReadRepository.find(request);
        saveDocumentLog(old,fresh,AllocateApplyOrderOperationTypeEnum.CANCELRECEIVED.getValue(),
                OperatorType.INNER_INTERFACE.getOperatorType(), Maps.newHashMap()
        );
        log.info("materialHandle_cancelReceived_response,material:{}, request:{}", allocateOrderCancelReceivedRequest.getOutMaterialCertificateId(), JSON.toJSONString(response));
        return Result.success(response);
    }

    private void saveDocumentLog(AllocateOrderInfo old,
                                 AllocateOrderInfo fresh,
                                 String operateType,
                                 Integer operatorType,
                                 Map<String,String> features){
        try{
            LoginUser loginUser = epochLoginUserService.getLoginUser();
            //因为日志表的长度限制, 现在日志没有用到子单明细,就把子单给缩略掉
            if (old != null){
                old.setDetails(Lists.newArrayList());
            }
            if (fresh != null){
                fresh.setDetails(Lists.newArrayList());
            }
            OpLogModel<AllocateOrderInfo> opLogModel = OpLogModel.<AllocateOrderInfo>builder()
                    .oldValue(old)
                    .newValue(fresh)
                    .moduleName(ModuleEnum.UNIFIED_INVENTORY.getModuleName())
                    .moduleId(ModuleEnum.UNIFIED_INVENTORY.getModuleId())
                    .dataType(OpLogDateTypeEnum.OBJECT_TYPE.getDataType())
                    .operateType(StringUtils.isBlank(operateType)?null:Integer.parseInt(operateType))
                    .operatorType(Optional.ofNullable(operatorType).orElse(OperatorType.USER.getOperatorType()))
                    .operatorId(loginUser.getEmpId())
                    .objectId(fresh.getId().toString())
                    .objectName(fresh.getCode())
                    .features(JSON.toJSONString(features))
//                    .objectId(fresh.getAllocateOrderSDO().getId().toString())
//                    .objectName(fresh.getAllocateOrderSDO().getCode())
                    .build();
            log.asyncMonitorObjectChangeV2(opLogModel);
        }catch (Throwable e) {
            log.error("调拨单日志写入失败:" , e);
            //这里要吃掉异常，防止影响主流程
            // throw e;
        }
    }

    /**
     * 调拨单日志写入
     * @param old
     * @param fresh
     */
    private void saveDocumentLog(AllocateOrderWithOrderDetailsSDO old,
                                 AllocateOrderWithOrderDetailsSDO fresh,
                                 Integer operateType,
                                 Integer operatorType){
        try{
            LoginUser loginUser = epochLoginUserService.getLoginUser();
            //因为日志表的长度限制, 现在日志没有用到子单明细,就把子单给缩略掉
            if (old != null){
                old.setAllocateOrderDetailSDOS(Lists.newArrayList());
            }
            if (fresh != null){
                fresh.setAllocateOrderDetailSDOS(Lists.newArrayList());
            }
            OpLogModel<AllocateOrderWithOrderDetailsSDO> opLogModel = OpLogModel.<AllocateOrderWithOrderDetailsSDO>builder()
                    .oldValue(old)
                    .newValue(fresh)
                    .moduleName(ModuleEnum.UNIFIED_INVENTORY.getModuleName())
                    .moduleId(ModuleEnum.UNIFIED_INVENTORY.getModuleId())
                    .dataType(OpLogDateTypeEnum.OBJECT_TYPE.getDataType())
                    .operateType(operateType)
                    .operatorType(Optional.ofNullable(operatorType).orElse(OperatorType.USER.getOperatorType()))
                    .operatorId(loginUser.getEmpId())
                    .objectId(fresh.getAllocateOrderSDO().getId().toString())
                    .objectName(fresh.getAllocateOrderSDO().getCode())
                    .build();
            log.asyncMonitorObjectChangeV2(opLogModel);
        }catch (Throwable e){
            log.error("调拨单日志写入失败:" , e);
            //这里要吃掉异常，防止影响主流程
            // throw  e;
        }
    }

    /**
     * 调拨预报单日志写入
     * @param oldValue
     * @param newValue
     * @param operateType
     * @param features
     */
    private void saveAllocateApplyOrderDocumentLog(AllocateApplyOrderDetailDTO oldValue, AllocateApplyOrderDetailDTO newValue, Integer operateType, Map<String, String> features) {
        try {
            LoginUser loginUser = epochLoginUserService.getLoginUser();
            if (Objects.nonNull(oldValue)) {
                oldValue.setList(null);
            }
            if (Objects.nonNull(newValue)) {
                newValue.setList(null);
            }
            OpLogModel<AllocateApplyOrderDetailDTO> opLogModel = OpLogModel.<AllocateApplyOrderDetailDTO>builder()
                    .oldValue(oldValue)
                    .newValue(newValue)
                    .moduleName(ModuleEnum.UNIFIED_INVENTORY.getModuleName())
                    .moduleId(ModuleEnum.UNIFIED_INVENTORY.getModuleId())
                    .operateType(operateType)
                    .operatorType(OperatorType.USER.getOperatorType())
                    .operatorId(loginUser.getEmpId())//操作人
                    .objectId(newValue.getId().toString())
                    .objectName(newValue.getCode())
                    .features(JSONObject.toJSONString(features))
                    .build();
            log.asyncMonitorObjectChangeV2(opLogModel);
        }catch (Throwable e){
            log.error("调拨单日志写入失败:" , e);
            //这里要吃掉异常，防止影响主流程
        }
    }

    @Override
    @FacadeInvoker(value = "牛要客更新调拨单外部单号",errorCode = "OTS-03-005-00-15-086")
    public Result<List<NykSaleOrderRise>> nykUpdateoAllocateOrderOutOrderId(NykSaleOrderRiseList nykSaleOrderRiseList) {
        List<NykSaleOrderRise> nykSaleOrderRiseReturns = new ArrayList<>();
        if (Objects.isNull(nykSaleOrderRiseList)||CollectionUtils.isEmpty(nykSaleOrderRiseList.getList())){
            return Result.success(nykSaleOrderRiseReturns);
        }
        List<NykSaleOrderRise> nykSaleOrderRises = nykSaleOrderRiseList.getList();
        List<String> failedDatas = new ArrayList<>();
        List<BatchRequest> batchRequests = new ArrayList<>();
        for (NykSaleOrderRise nykSaleOrderRise : nykSaleOrderRises){
            //根据调拨单外部编号获取调拨单主单信息
            AllocateOrderDetailsQueryRequest allocateOrderDetailsQueryRequest = new AllocateOrderDetailsQueryRequest();
            allocateOrderDetailsQueryRequest.setOutAllocateOrderId(nykSaleOrderRise.getId());
            AllocateOrderSDO allocateOrderSDO = allocateOrderReadRepository.query(allocateOrderDetailsQueryRequest);
            if (Objects.nonNull(allocateOrderSDO)&&StringUtils.isNotBlank(nykSaleOrderRise.getVbakVbeln())) {
                allocateOrderSDO.setNykId(nykSaleOrderRise.getVbakVbeln());
                allocateOrderWriteRepository.updata(allocateOrderSDO);
                nykSaleOrderRiseReturns.add(nykSaleOrderRise);
            }else{
                failedDatas.add(nykSaleOrderRise.getId());
                BatchRequest batchRequest = new BatchRequest();
                batchRequest.setType(4);
                batchRequest.setSapCode(nykSaleOrderRise.getVbakVbeln());
                batchRequest.setOrderId(nykSaleOrderRise.getId());
                batchRequest.setFailureReason("没找到平台中牛要客数据");
                batchRequests.add(batchRequest);
            }
        }
        //保存失败的数据
        BatchCreateRequest batchCreateRequest =new BatchCreateRequest();
        batchCreateRequest.setBatchRequest(batchRequests);
        if (CollectionUtils.isNotEmpty(batchRequests)) {
            ouiNykFailRecordService.batchCreate(batchCreateRequest);
        }
        log.info("AllocateOrderWriteServiceImpl.nykUpdateoAllocateOrderOutOrderId,failedDatas:{}",JSONObject.toJSONString(failedDatas));
        return Result.success(nykSaleOrderRiseReturns);
    }

    /**
     * 订正数据后修正调拨单和明细的状态
     * @param allocateOrderFixStatusRequest
     * @return
     */
    @Override
    public Result<AllocateOrderFixStatusResponse> fixStatus(AllocateOrderFixStatusRequest allocateOrderFixStatusRequest) {
        AllocateOrderFixStatusResponse response = new AllocateOrderFixStatusResponse();
        if (Objects.isNull(allocateOrderFixStatusRequest) || StringUtils.isBlank(allocateOrderFixStatusRequest.getOutAllocateOrderIds())){
            return Result.success(response);
        }
        String[] idArray = allocateOrderFixStatusRequest.getOutAllocateOrderIds().split(",");
        if (idArray == null || idArray.length == 0){
            return Result.success(response);
        }
        Set<String> set = Stream.of(idArray).collect(Collectors.toSet());
        Set<String> resSet = Sets.newHashSet();
        for (String outAllocateOrderId : set) {
            if (StringUtils.isBlank(outAllocateOrderId)){
                continue;
            }
            try(RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(),ALLOCATE_ORDER_LOCK_SYNC + outAllocateOrderId,5 * 60 * 1000,10 * 60 * 1000)) {
                if (!lock.lock()) {
                    throw new FacadeException("OTS-03-005-00-15-096");
                }
                boolean success = allocateOrderWriteRepository.fixStatus(outAllocateOrderId);
                if (success){
                    resSet.add(outAllocateOrderId);
                }
            }catch (Exception e){
                log.error("fixStatus",e);
                continue;
            }
        }
        if (CollectionUtils.isNotEmpty(resSet)){
            response.setOutAllocateOrderIds(resSet.stream().collect(Collectors.joining(",")));
        }
        return Result.success(response);
    }

    //修正调拨单的交货数量
    @Override
    public Result<AllocateOrderFixDeliveryQuantityResponse> fixDeliveryQuantity(AllocateOrderFixDeliveryQuantityRequest allocateOrderFixDeliveryQuantityRequest) {
        AllocateOrderFixDeliveryQuantityResponse response = new AllocateOrderFixDeliveryQuantityResponse();
        if (Objects.isNull(allocateOrderFixDeliveryQuantityRequest) || StringUtils.isBlank(allocateOrderFixDeliveryQuantityRequest.getOutAllocateOrderIds())){
            return Result.success(response);
        }
        String[] idArray = allocateOrderFixDeliveryQuantityRequest.getOutAllocateOrderIds().split(",");
        if (idArray == null || idArray.length == 0){
            return Result.success(response);
        }
        Set<String> set = Stream.of(idArray).collect(Collectors.toSet());
        Set<String> resSet = Sets.newHashSet();
        for (String outAllocateOrderId : set) {
            if (StringUtils.isBlank(outAllocateOrderId)){
                continue;
            }
            try(RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(),ALLOCATE_ORDER_LOCK_SYNC + outAllocateOrderId,5 * 60 * 1000,10 * 60 * 1000)) {
                if (!lock.lock()) {
                    throw new FacadeException("OTS-03-005-00-15-096");
                }
                boolean success = allocateOrderWriteRepository.fixDeliveryQuantity(outAllocateOrderId);
                if (success){
                    resSet.add(outAllocateOrderId);
                }
            }catch (Exception e){
                log.error("fixDeliveryQuantity",e);
                continue;
            }
        }
        if (CollectionUtils.isNotEmpty(resSet)){
            response.setOutAllocateOrderIds(resSet.stream().collect(Collectors.joining(",")));
        }
        return Result.success(response);
    }

    /**
     * 获取外部调拨单号
     * @param sdo 入参
     * @return 外部调拨单号
     */
    private String getOutAllocateOrderId(AllocateOrderWithOrderDetailsSDO sdo) {
        if (Objects.isNull(sdo) || Objects.isNull(sdo.getAllocateOrderSDO())) {
            return null;
        }
        return sdo.getAllocateOrderSDO().getOutAllocateOrderId();
    }
}
